﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace AnesSystem.Controls
{
    /// <summary>
    /// CusDatePicker.xaml 的交互逻辑
    /// </summary>
    public partial class CusDatePicker : UserControl
    {
        #region Variables

        VerifierTextBoxCtrl selected;
        DateTime _time;

        #endregion

        #region Constructor

        public CusDatePicker()
        {
            InitializeComponent();
            DisplayModel = 2;
            textBlockhh.GotFocus += Text_GotFocus;
            textBlockmm.GotFocus += Text_GotFocus;
            textBlockhh.LostFocus += Text_LostFocus;
            textBlockmm.LostFocus += Text_LostFocus;
        }

        private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            VerifierTextBoxCtrl ctrl = sender as VerifierTextBoxCtrl;
            ctrl._txt.Focus();
            e.Handled = true;
        }

        #endregion

        #region Properties

        /// <summary>
        /// 显示模式 1：年月日 2：月日
        /// </summary>
        public int DisplayModel { get; set; }

        public bool Result { get; set; }

        #endregion

        #region 依赖属性



        public Thickness DateBorderThickness
        {
            get { return (Thickness)GetValue(DateBorderThicknessProperty); }
            set { SetValue(DateBorderThicknessProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DateBorderThickness.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DateBorderThicknessProperty =
            DependencyProperty.Register("DateBorderThickness", typeof(Thickness), typeof(CusDatePicker), new PropertyMetadata(new Thickness(2)));



        public Visibility CalendarVisibility
        {
            get { return (Visibility)GetValue(CalendarVisibilityProperty); }
            set { SetValue(CalendarVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CalendarVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CalendarVisibilityProperty =
            DependencyProperty.Register("CalendarVisibility", typeof(Visibility), typeof(CusDatePicker), new PropertyMetadata(Visibility.Collapsed));



        public Visibility HMVisibility
        {
            get { return (Visibility)GetValue(HMVisibilityProperty); }
            set { SetValue(HMVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HMVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HMVisibilityProperty =
            DependencyProperty.Register("HMVisibility", typeof(Visibility), typeof(CusDatePicker), new PropertyMetadata(Visibility.Visible));



        public Visibility DateVisibility
        {
            get { return (Visibility)GetValue(DateVisibilityProperty); }
            set { SetValue(DateVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DateVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DateVisibilityProperty =
            DependencyProperty.Register("DateVisibility", typeof(Visibility), typeof(CusDatePicker), new PropertyMetadata(Visibility.Visible));


        public Visibility ExcuteVisibility
        {
            get { return (Visibility)GetValue(ExcuteVisibilityProperty); }
            set { SetValue(ExcuteVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ExcuteVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ExcuteVisibilityProperty =
            DependencyProperty.Register("ExcuteVisibility", typeof(Visibility), typeof(CusDatePicker), new PropertyMetadata(Visibility.Collapsed));



        public bool IsOpen
        {
            get { return (bool)GetValue(IsOpenProperty); }
            set { SetValue(IsOpenProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsOpen.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsOpenProperty =
            DependencyProperty.Register("IsOpen", typeof(bool), typeof(CusDatePicker), new PropertyMetadata(false));




        public double HMWidht
        {
            get { return (double)GetValue(HMWidhtProperty); }
            set { SetValue(HMWidhtProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HMWidht.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HMWidhtProperty =
            DependencyProperty.Register("HMWidht", typeof(double), typeof(CusDatePicker), new PropertyMetadata());



        public double HMHeight
        {
            get { return (double)GetValue(HMHeightProperty); }
            set { SetValue(HMHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HMHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HMHeightProperty =
            DependencyProperty.Register("HMHeight", typeof(double), typeof(CusDatePicker), new PropertyMetadata());



        public double CalendarWidth
        {
            get { return (double)GetValue(CalendarWidthProperty); }
            set { SetValue(CalendarWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CalendarWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CalendarWidthProperty =
            DependencyProperty.Register("CalendarWidth", typeof(double), typeof(CusDatePicker), new PropertyMetadata(400.0));

        public double CalendarHeight
        {
            get { return (double)GetValue(CalendarHeightProperty); }
            set { SetValue(CalendarHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CalendarWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CalendarHeightProperty =
            DependencyProperty.Register("CalendarHeight", typeof(double), typeof(CusDatePicker), new PropertyMetadata(400.0));

        public DateTime SelectedDateTime
        {
            get { return (DateTime)GetValue(SelectedDateTimeProperty); }
            set { SetValue(SelectedDateTimeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedDateTime.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedDateTimeProperty =
            DependencyProperty.Register("SelectedDateTime", typeof(DateTime), typeof(CusDatePicker), new PropertyMetadata(SelectedDateTimeChangedCallBack));

        private static void SelectedDateTimeChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                try
                {
                    CusDatePicker ctrl = d as CusDatePicker;
                    ctrl._calendar.SelectedDatesChanged -= ctrl._calendar_SelectedDatesChanged;
                    try
                    {
                        ctrl._calendar.SelectedDate = (DateTime)e.NewValue;
                    }
                    catch (Exception)
                    {
  //                      ctrl._calendar.SelectedDate = (DateTime)e.NewValue;
                    }
                    DateTime time = (DateTime)e.NewValue;
                    ctrl.YearMD = time.ToString(DateFormat.DATE_FORMAT_STR_YMD);
                    ctrl.Hour = time.Hour;
                    ctrl.Minute = time.Minute;
                    if (ctrl.DisplayModel == 1)
                    {
                        ctrl.DisplayDate = ctrl.YearMD;
                    }
                    else
                    {
                        ctrl.DisplayDate = time.Month + "-" + time.Day;
                    }
                    ctrl._calendar.SelectedDatesChanged += ctrl._calendar_SelectedDatesChanged;
                }
                catch (Exception ex)
                {
                    Common.LogHelper.Error("CusDatePicker", ex);

                }
            }
        }

        public string DisplayDate
        {
            get { return (string)GetValue(MDProperty); }
            set { SetValue(MDProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MD.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MDProperty =
            DependencyProperty.Register("DisplayDate", typeof(string), typeof(CusDatePicker), new PropertyMetadata(DateTime.Now.ToString(DateFormat.DATE_FORMAT_STR_YMD)));



        public string YearMD
        {
            get { return (string)GetValue(YearMDProperty); }
            set { SetValue(YearMDProperty, value); }
        }

        // Using a DependencyProperty as the backing store for YearMD.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty YearMDProperty =
            DependencyProperty.Register("YearMD", typeof(string), typeof(CusDatePicker), new PropertyMetadata(DateTime.Now.ToString(DateFormat.DATE_FORMAT_STR_YMD)));



        public int Hour
        {
            get { return (int)GetValue(HourProperty); }
            set { SetValue(HourProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Hour.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HourProperty =
            DependencyProperty.Register("Hour", typeof(int), typeof(CusDatePicker), new PropertyMetadata(DateTime.Now.Hour, HourAndMinuteChangedCallBack));

        private static void HourAndMinuteChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

            if (e.NewValue != null)
            {
                CusDatePicker ctrl = d as CusDatePicker;
                try
                {
                    if (e.Property.Name.Equals("Hour"))
                    {
                        int houre = int.Parse(e.NewValue.ToString());
                        if (houre >= 24 || houre < 0)
                        {
                            MessageBoxCommon.ShowDialog("请输入正确的时间！", 0);
                            ctrl.Hour = int.Parse(e.OldValue.ToString());
                        }
                    }
                    else if (e.Property.Name.Equals("Minute"))
                    {
                        int minute = int.Parse(e.NewValue.ToString());
                        if (minute >= 60 || minute < 0)
                        {
                            MessageBoxCommon.ShowDialog("请输入正确的时间！", 0);
                            ctrl.Minute = int.Parse(e.OldValue.ToString());
                        }
                    }
                    ctrl.RefSelectedDateTime();
                }
                catch (Exception ex)
                {
                    Common.LogHelper.Error(ctrl.GetType(), ex);
                }
            }
        }

        public int Minute
        {
            get { return (int)GetValue(MinuteProperty); }
            set { SetValue(MinuteProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Minute.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MinuteProperty =
            DependencyProperty.Register("Minute", typeof(int), typeof(CusDatePicker), new PropertyMetadata(DateTime.Now.Minute, HourAndMinuteChangedCallBack));


        #endregion

        #region Event

        public event EventHandler DateSelected;

        #endregion

        #region Private Methods

        private void RefSelectedDateTime()
        {

            try
            {
                if (HMVisibility == Visibility.Collapsed)
                {
                    _time = DateTime.Parse(YearMD + " " + Hour + ":" + Minute);
                }
                else
                {
                    SelectedDateTime = DateTime.Parse(YearMD + " " + Hour + ":" + Minute);
                }
            }
            catch (Exception ex)
            {

                Common.LogHelper.Error(this.GetType(), ex);
            }
        }

        #endregion

        #region Public/Protected Methods

        #endregion

        #region EventHandlers

        private void Up_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;

            if (btn == null) return;
            int temp;
            if (btn.Tag.Equals("hour"))
            {
                temp = Hour;
                temp++;
                if (temp > 23)
                {
                    temp = 0;
                }
                Hour = temp;
            }
            else if (btn.Tag.Equals("minute"))
            {
                temp = Minute;
                temp++;
                if (temp > 59)
                {
                    temp = 0;
                }
                Minute = temp;
            }
            RefSelectedDateTime();
        }
        private void Down_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;

            if (btn == null) return;
            int temp = 0;
            if (btn.Tag.Equals("hour"))
            {
                temp = Hour;
                temp--;
                if (temp < 0)
                {
                    temp = 23;
                }
                Hour = temp;
            }
            else if (btn.Tag.Equals("minute"))
            {
                temp = Minute;
                temp--;
                if (temp < 0)
                {
                    temp = 59;
                }
                Minute = temp;
            }
            RefSelectedDateTime();
        }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            RefSelectedDateTime();
            SelectedDateTime = _time;
            Result = true;
            DateSelected?.Invoke(this, null);
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            Result = false;
            DateSelected?.Invoke(this, null);
        }

        private void Text_LostFocus(object sender, RoutedEventArgs e)
        {
            VerifierTextBoxCtrl ctrl = sender as VerifierTextBoxCtrl;
            ctrl._txt.SelectionLength = 0;
            IsOpen = false;
        }

        private void Text_GotFocus(object sender, RoutedEventArgs e)
        {
            VerifierTextBoxCtrl ctrl = sender as VerifierTextBoxCtrl;

            selected = ctrl;
        }

        private void _calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
            YearMD = _calendar.SelectedDate.Value.ToString(DateFormat.DATE_FORMAT_STR_YMD);
            RefSelectedDateTime();
        }

        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            CusDatePickerWin win = new CusDatePickerWin();
            win.SelectedDateTime = SelectedDateTime;
            win.ShowDialog();
            SelectedDateTime = win.SelectedDateTime;
        }

        #endregion


    }
}
